搭建 Spring MVC 框架踩坑记
0X00 前言
出于出LCTF 2018 题目的原因,不得不自己搭建一个 Spring MVC 框架,虽然这只是一地步,但是踩了无数的坑,我在这里简单的记录一下
0X01 创建项目
怎么创建项目呢,创建什么项目呢?这本身就是一个问题,后来在TG师傅的指点下,我最终选择了使用 maven 的方式创建项目,因为这种方法使用 pom.xml 统一管理 jar 包,添加和管理都很方便
如图所示:
这里选择 release 或者1.3 都可以,但是这其实是一个坑(这个坑后面会遇到 el 不支持的问题,我们后面再解决)
选择好了以后,我们填写一些基本的信息
如图所示:
groupid 是填写类似于包名的内容,因为是本地项目,对我的意义不大,随便写一下,artifactld 是填写你当前项目的名称(这两个选项待会我们还会遇见类似的在 pom.xml 里面,我们待会介绍)
然后我们 next ,这里 settings.xml 文件默认是不存在在那个目录下的,我们需要从 IDEA 的原始目录中拷贝(IDEA 似乎自带了两个版本的 maven 如果你选择了3 那就拷贝 3下面的 settings.xml 如果是二就以此类推),我的路径是
D:\IDEA\IntelliJ IDEA 2018.2.4\plugins\maven\lib\maven3\conf\settiungs.xml
拷贝完以后,我们需要对这个文件进行修改,因为我国的国情,原来的源是不能用的,我们要换国内源
在 <mirrors>
标签里面加上下面的语句
<id>alimaven</id>
<mirrorOf>central</mirrorOf>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
然后我们就下一步下一步,然后就静静等待项目框架加载完毕
0X02 配置 pom.xml
完毕以后我们就能修改 pom.xml 添加依赖,这里指的就是下载一些必要的 jar 包
以下是我添加进去的内容
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>javax/servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>javax/servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.0.6</version>
</dependency>
这里面的命名规则是什么?
groupid 就是这个 Jar 所在的远程的包的名字
artifactId 就是这个包自己的名字
version 就是版本
这里我推荐一个网站,能清楚地查询这些信息
补充一点:
如果想包随着 pom.xml 实时更新的话,可以在 File->settings->Build.Execution,Deployment->Build Tools-> Maven 里面选择 Always update snapashots
0X03 添加框架依赖
到刚刚为止我们只是简单地创建了一个项目,是不是感觉和 spring 一点关系都没有,没错!于是我们现在要添加框架依赖
右键我们的项目,选择 add framework support
如图所示:
选择 Spring 在选择 Spring MVC
如图所示:
这里注意两点:
(1)要勾选那个自动创建配置文件的选项(这个选项在选择 Spring 的时候出现,但是选择 Spring MVC 的时候没有)
(2)如果框架选项里面没有 Spring ,那估计是在你的 project structor 里面 的 modules 里面配置了一个 spring 这可能是由于加载依赖的时候自动弄得,我们要手动删除
如图所示:
添加完框架依赖的目录结构如图:
框起来的部分就是他自动生成的配置文件
0X04 完善目录结构
我们一般在 WEB-INF 里面添加的是 静态文件已经 jsp 视图文件,main 里面添加一个叫做 java的 资源文件夹用来放控制器,再添加一个 resources 作为资源文件夹,再在 src 同级建一个 target 作为导出目录
如图所示:
但是创建完毕以后我们发现,我们没法再 java 文件夹中创建 class 或者 package ,这是因为我们还没有给他们模型,我们要到 project structor 里面去设置
如图所示:
可以看到变了颜色,这就说明设置好了,我们就可以创建我们的项目了
0X05 写项目
首先配置 web.xml 这是整个项目的配置文件,我们最后要根据这个文件的配置去找我们的 servlet
示例配置:
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
注意:
(1)其中 org.springframework.web.servlet.DispatcherServlet 非常重要,这个是 spring 框架的核心,就是他根据我们传过来的名字 去寻找对应的 servlet 的配置文件的
(2) 其中 / 表示根路径的全部请求都用 dispatcher 这个 servlet 来接收
配置好了项目的配置文件,我们再继续配置 servlet 的配置文件,这个文件我们如果需要可以手动创建,命名规则就是 servlet名-servlet.xml ,因为初始化的时候 servlet 就叫 dispatcher 我们又选了自动生成,于是这个配置文件已经有了,我们只需要修改,如果没有,我们就要另外创建
dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<context:component-scan base-package="com.spring" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
其中
<context:component-scan base-package="com.spring" />
这部分是用来扫描包的,这个包就是我们应该在 java 文件夹中创建的包的前两个节点,比如我们创建 com.spring.test 这个包,那我们就写 com.spring
但是为了实现这个功能,光写这个还不够,我们还需要添加 beans 的内容,添加下面这两行
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
然后我们需要指定我们的 视图存在位置和后缀名
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
然后我们写 controller
HelloController.java
package com.spring.test;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
@RequestMapping("/hello")
public class HelloController {
@RequestMapping(method = RequestMethod.GET)
public String printHello(ModelMap model){
model.addAttribute("message","Hello Spring MVC FrameWork");
return "hello";
}
}
我们写 jsp
hello.jsp
<%@ page contentType="text/html; charset=UTF-8" %>
<html>
<head>
<title>Hello World</title>
</head>
<body>
<h2>Hello, ${message}</h2>
</body>
</html>
坑点:
这里面最坑的就是没法解析 el 语句,因为我们下载的 web.xml 是 2.3 版本,以后的版本就支持了,所以为了解决这个问题我们需要修改一下 web.xml 的头
注释掉下面这一部分:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
修改一部分成下面这个样子
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
然后再添加我们本地的 tomcat 项目就能运行了
0X06 扩展
如果我们想写多个 servlet 的话,我们可以把 web.xml 改成下面这个样子,这样他会去找不同的 servlet 配置文件实现不同的功能,而在这种情况下, controller 里面的路由是基于 web.xml 的,比如 web.xml 配置 /error/* 的都去找 erorController ,然后 controller 写的是 /error ,那我们最终访问的时候就是 /error/error才能访问到这个控制器
web.xml部分内容
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/right/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>error</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>error</servlet-name>
<url-pattern>/error/*</url-pattern>
</servlet-mapping>
0X07 总结
这篇文章只是搭建框架中的一点记录防止忘记,以后还要深入学习。